#include <stdio.h>
#include <mqueue.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <time.h>
#include <string.h>

#define MAXSIZE     10   //定义buf大小
#define BUFFER      8192 //定义Msg大小

mqd_t mqdes;
struct MsgType{
    int len;
    char buf[MAXSIZE];
    char x;
    short y;
};

static void                     /* Thread start function */
message_callback(union sigval sv)
{
    struct mq_attr attr;
	struct MsgType msg;
    unsigned int recv_size = BUFFER;	
    ssize_t nr;
    mqd_t mqdes = *((mqd_t *) sv.sival_ptr);


    /* Determine maximum msg size; allocate buffer to receive msg */


    if (mq_getattr(mqdes, &attr) == -1) {
        perror("mq_getattr");
        exit(EXIT_FAILURE);
    }

	msg.len = -1;
	memset(msg.buf, 0, MAXSIZE);
	msg.x = ' ';
	msg.y = -1;	

	/* getting a message */
	/*mq_receive() 从由描述符 mqdes 引用的队列时删除优先级最高的最老的消息，并把放置到 msg_ptr 的缓存区内。*/
	/*参数 msg_len 指定缓冲区 msg_ptr 的大小：它必须大于队列的 mq_msgsize 属性(参数 mq_getattr)。*/ 
	/*如果 prio 不是 NULL，那么它指向的内存用于返回收到消息相关的优先级。*/
	if (mq_receive(mqdes, (char*)&msg, attr.mq_msgsize, NULL) == -1) 
	{
		perror("mq_receive");
		exit(1);
	}
	printf("mq_receive: thread_id = %d, msg.len = %d, msg.buf = %s, msg.x = %c, msg.y = %d\n",getpid(), msg.len, msg.buf, msg.x, msg.y);
    exit(EXIT_SUCCESS);         /* Terminate the process */
}


int
main(int argc, char *argv[])
{
    struct sigevent sev;	
    struct MsgType msg;	
    mqd_t mqdes = mq_open("/posix", O_CREAT | O_RDWR, 0777, NULL);
    if (mqdes == (mqd_t) -1) {
        perror("mq_open");
        exit(EXIT_FAILURE);
    }

	bzero(&sev, sizeof(sev));
    sev.sigev_notify = SIGEV_THREAD;
    sev.sigev_notify_function = message_callback;
    sev.sigev_notify_attributes = NULL;
    sev.sigev_value.sival_ptr = &mqdes;   /* Arg. to thread func. */

	msg.len = atoi(argv[1]);
	memset(msg.buf, 0, MAXSIZE);
	sprintf(msg.buf, "0x%x", atoi(argv[1]));
	msg.x = (char)(atoi(argv[1]) + 'a');
	msg.y = (short)(atoi(argv[1]) + 100);
	printf("mq_send: thread_id = %d, msg.len = %d, msg.buf = %s, msg.x = %c, msg.y = %d\n",getpid(), msg.len, msg.buf, msg.x, msg.y);
	if (mq_notify(mqdes, &sev) == -1) {
		perror("mq_notify");
		exit(EXIT_FAILURE);
	}
	sleep(1);
	/*sending the message      --  mq_send() */
	/*mq_send() 把 msg_ptr 指向的消息加入由 mqdes 引用的消息队列里。*/
	/*参数 msg_len 指定消息 msg_ptr 的长度：这个长度必须小于或等于队列 mq_msgsize 属性的值。零长度的消息是允许。*/
	if(mq_send(mqdes, (char*)&msg, sizeof(struct MsgType), 1) == -1)
	{
		perror("mq_send");
		exit(1);
	}
	pause();    /* Process will be terminated by thread function */	

    exit(EXIT_SUCCESS);	
}